package cyou.breathe.yuque;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import cyou.breathe.constant.Constant;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URLDecoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * @author: breathe
 * @createTime: 2025-7-8
 */
public class YuqueDownloader {
    private final HttpClient client;
    private final String cookie;
    private final String outputDir;

    public YuqueDownloader(String cookie, String outputDir) {
        this.cookie = cookie;
        this.outputDir = outputDir;
        this.client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10))
                .build();
    }

    public void downloadBook(String url) {
        try {
            String html = httpGet(url);
            String jsonEncoded = extractJson(html);
            JsonNode root = new ObjectMapper().readTree(URLDecoder.decode(jsonEncoded, StandardCharsets.UTF_8));
            String bookTitle = root.path("book").get("slug").asText() + Constant.SEPARATOR + root.path("book").get("name").asText();
            Path bookDir = Paths.get(outputDir, bookTitle);
            //如果目录存在，先删除再创建
            if (Files.exists(bookDir)) {
                //目录原本存在，删除所有文件
                System.out.println("bookTitle: " + bookTitle + "已存在，正在删除...");
                try (Stream<Path> paths = Files.walk(bookDir)) {
                    paths.sorted((o1, o2) -> o2.toString().length() - o1.toString().length())
                         .map(Path::toFile)
                         .forEach(file -> {
                             if (!file.delete()) {
                                 System.err.println("无法删除文件: " + file.getAbsolutePath());
                             }
                         });
                } catch (IOException e) {
                    System.err.println("删除文件时出错: " + e.getMessage());
                }
                System.out.println("bookTitle: " + bookTitle + "已删除");
            }
            Files.createDirectories(bookDir);
            JsonNode toc = root.path("book").path("toc");
            TocProcessor processor = new TocProcessor(bookDir, root.path("book").path("id").asText(), cookie);
            processor.processToc(toc);
            Files.writeString(bookDir.resolve("SUMMARY.md"), processor.getSummaryMarkdown());
        } catch (Exception e) {
            System.err.println("下载失败: " + e.getMessage());
        }
    }

    private String extractJson(String html) {
        Matcher m = Pattern.compile("decodeURIComponent\\(\"(.+?)\"\\)\\);").matcher(html);
        if (m.find()) {
            return m.group(1);
        }
        throw new IllegalStateException("未找到 JSON 数据");
    }

    private String httpGet(String url) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(10))
                .header("Cookie", cookie)
                .GET()
                .build();
        return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
    }
}
